import { ServerVo } from "./ServerVo";
import { LZString } from "../../app_cocos/libs/lz-string";
import { app } from "../../base";
import { Handler } from "../../app_base/base/utils/Handler";

const ServerConfig = {
    domain: "https://api.game.hnquyou.com",
    configAPI: "/api/game-common/app/config/get"
}

/**
 @name: IServer
 @desc: 服务器数据
 @author: timoo
 @date: 2022/11/30
 */
export class Server {
    private _vo: ServerVo;
    private _serverTime: number;
    private _startedAppTime: number;
    init(): Server {
        if (!this._vo) {
            this._vo = new ServerVo();
        }
        return this;
    }

    public set time(time: number) {
        this._serverTime = time;
        this._startedAppTime = Date.now();
        console.log("更新服务器时间：", time);
    }

    /**
     * 服务器时间戳 毫秒
     */
    public get time(): number {
        if (this._serverTime) {
            return this._serverTime + Date.now() - this._startedAppTime;
        }
        return Date.now();
    }

    /**
     * 服务器日期对象
     */
    public get date(): Date {
        return new Date(this.time)
    }

    /**
     * 服务器配置数据
     */
    public get data(): ServerVo {
        return this._vo;
    }

    public requestConfig(): Promise<void> {
        return new Promise((resolve) => {
            app.net.http.post(
                ServerConfig.domain + ServerConfig.configAPI,
                {
                    responseType: "json",
                    data: this._getConfigParams(),
                    onComplete: Handler.create(this, (data) => {
                        console.log(`[S=>C](${ServerConfig.configAPI} ${JSON.stringify(data)})=>`)
                        if (data && data.timestamp) {
                            let time = Number(data.timestamp);
                            if (!Number.isNaN(time)) {
                                this.time = time;
                            }
                        }
                        if (data && data.data && data.code == "200" && data.message == "success") {
                            this._updateConfig(data.data);
                            resolve();
                            return;
                        }
                        this._updateConfig();
                        resolve();
                    }),
                    onError: Handler.create(this, () => {
                        this._updateConfig();
                        resolve();
                    })
                })
        });
    }

    private _getConfigParams(): object {
        return {
            appid: app.publisher.appId,
            version: app.publisher.appVersion,
        }
    }

    private _updateConfig(data?: { global: any, extra: any, version: string }): void {
        data = data || app.storage.getGValue("ServerData", { global: {}, extra: {}, version: app.publisher.appVersion });
        for (const key in data.global) {
            if (Object.prototype.hasOwnProperty.call(data.global, key)) {
                let value = data.global[key];
                this._vo[key] = value;
            }
        }

        if (data.version == app.publisher.appVersion) {
            for (const key in data.extra) {
                if (Object.prototype.hasOwnProperty.call(data.extra, key)) {
                    let value = data.extra[key];
                    if (data.global[key]) {
                        console.warn(`警告：版本[${data.version}]配置${key}:${value} 覆盖全局配置${key}:${data.global[key]}`)
                    }
                    this._vo[key] = value;
                }
            }
        }

        //根据特殊字段bundle设置bundle版本
        const bundleVersion = this._vo['bundle'];
        if (bundleVersion) {
            let map: Map<string, string> = new Map();
            for (const bundleName in bundleVersion) {
                if (Object.prototype.hasOwnProperty.call(bundleVersion, bundleName)) {
                    const version = bundleVersion[bundleName];
                    map.set(bundleName, version);
                }
            }
            app.res.setBundleVersion(map);
        }

        app.storage.setGValue("ServerData", this._vo.toString());
    }
}